package com.yunxi.core.web;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import java.lang.reflect.Method;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 */
public class Model extends HashMap {

    public Model set(String key,Object value){
        this.put(key,value);
        return this;
    }

    public <T> T take(String key){
        return (T)get(key);
    }
    
    protected Log log = LogFactory.getLog(this.getClass());

    public Model() {

    }

    /**
     * ͨ���ַ������ʼ��MapBean
     *
     * @param init
     */
    public Model(String[][] init) {
        if (init != null) {
            for (int i = 0; i < init.length; i++) {
                String key = init[i][0];
                String value = init[i][1];
                if (key != null && !key.equals("")) {
                    this.put(key, value);
                }
            }
        }
    }

    /**
     * ͨ����������ʼ��MapBean
     *
     * @param init
     */
    public Model(Object[][] init) {
        if (init != null) {
            for (int i = 0; i < init.length; i++) {
                Object key = init[i][0];
                Object value = init[i][1];
                if (key != null) {
                    this.put(key, value);
                }
            }
        }
    }

    /**
     * ����key-value
     */
    @Override
    public Object put(Object key, Object value) {
        Object obj = null;
        if (key != null && key instanceof String) {
//            super.put(((String) key).toLowerCase(), value);
//            super.put(((String) key).toUpperCase(), value);
            obj = super.put(key, value);
        }
        return obj;
    }

    /**
     * ��ȡint����ֵ�����ֵΪnull���򷵻�0
     *
     * @param key
     * @return
     */
    public int getInt(Object key) {
        return getInt(key, 0);
    }

    /**
     * ��ȡint����ֵ�����ֵΪnull���򷵻ظ��Ĭ��ֵ
     *
     * @param key
     * @param defaultValue
     * @return
     */
    public int getInt(Object key, int defaultValue) {
        Object value = get(key);
        if (value == null) {
            return 0;
        } else {
            Integer d = null;
            try {
                d = new Integer(String.valueOf(value));
            } catch (NumberFormatException e) {
                d = defaultValue;
            }
            return d.intValue();
        }
    }

    /**
     * ��ȡlong������ֵ�����ֵΪnull���򷵻�0
     *
     * @param key
     * @return
     */
    public long getLong(Object key) {
        return getLong(key, 0);
    }

    /**
     * ��ȡlong������ֵ�����ֵΪnull���򷵻�ָ����Ĭ��ֵ
     *
     * @param key
     * @param defaultValue Ĭ��ֵ
     * @return
     */
    public long getLong(Object key, long defaultValue) {
        Object value = get(key);
        if (value == null) {
            return 0;
        } else {
            Long d = null;
            try {
                d = new Long(String.valueOf(value));
            } catch (NumberFormatException e) {
                d = defaultValue;
            }
            return d.longValue();
        }
    }

    /**
     * ��ȡdouble������ֵ�����ֵΪnull����Ĭ�Ϸ���0
     *
     * @param key
     * @return
     */
    public double getDouble(Object key) {
        return getDouble(key, 0);
    }

    /**
     * ��ȡdouble������ֵ�����ֵΪnull���򷵻�ָ����Ĭ��ֵ
     *
     * @param key
     * @param defaultValue Ĭ��ֵ
     * @return
     */
    public double getDouble(Object key, double defaultValue) {
        Object value = get(key);
        if (value == null) {
            return 0;
        } else {
            Double d = null;
            try {
                d = new Double(String.valueOf(value));
            } catch (NumberFormatException e) {
                d = defaultValue;
            }
            return d.doubleValue();
        }
    }

    /**
     * ��ȡ�ַ�ֵ
     *
     * @param key
     * @return
     */
    public String getString(Object key) {
        Object obj = get(key);
        if (obj != null) {
            return String.valueOf(obj);
        } else {
            return null;
        }
    }

    /**
     * ��ȡ�ַ�ֵ���������Ϊnull���򷵻ظ��Ĭ��ֵ
     *
     * @param key
     * @param defaultValue Ĭ��ֵ
     * @return
     */
    public String getString(Object key, String defaultValue) {
        Object obj = get(key);
        if (obj != null) {
            return String.valueOf(obj);
        } else {
            return defaultValue;
        }
    }

    /**
     * ��ȡ���ڶ���
     *
     * @param key
     * @return
     */
    public Date getDate(Object key) {
        Object object = get(key);
        if (object == null) {
            return null;
        } else {
            Date date = null;
            try {
                date = (Date) get(key);
            } catch (Exception e) {
                date = getOracleTimestamp(object);
            }

            return date;
        }
    }

    private Timestamp getOracleTimestamp(Object value) {
        try {
            Class clz = value.getClass();
            Method m = clz.getMethod("timestampValue", null);
            // m = clz.getMethod("timeValue", null); ʱ������
            // m = clz.getMethod("dateValue", null); ��������
            return (Timestamp) m.invoke(value, null);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * ��ȡָ�����ڸ�ʽ���ַ�
     *
     * @param key
     * @param pattern
     * @return
     */
    public String getFormatDate(Object key, String pattern) {
        SimpleDateFormat format = new SimpleDateFormat(pattern);
        Date date = getDate(key);
        if (date == null) {
            return null;
        } else {
            return format.format(date);
        }
    }

    /**
     * ��ȡĬ�ϸ�ʽ�������ַ�Ĭ�ϸ�ʽ��yyyy-MM-dd
     *
     * @param key
     * @return
     */
    public String getFormatDate(Object key) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Date date = getDate(key);
        if (date == null) {
            return null;
        } else {
            return format.format(date);
        }
    }

    /**
     * ��ȡ��ʾֵ������listҳ����table��ݵ���ʾ
     * ����ֵΪ����ʾ���˴��?���ı����������textarea��װ��ʾ��������������ݺ��Բ���ʾ��
     *
     * @param key
     * @param simple_type �����ͣ�1���ַ�  2������  3��������  4�����ı�  5��������  6��������
     * @param format      ��ʾ��ʽ
     * @return
     */
    public String getDisplayValue(String key, int simple_type, String format) {
        String value = "";
        if (this.get(key) == null) {
            return "";
        }

        switch (simple_type) {
            case 1: // 1���ַ�
                value = this.getString(key);
                try {
                    if (format != null && !format.equals("")) { // ���format��Ϊ�գ���ʾҪ����ʾ��λ�ַ�
                        int length = Integer.parseInt(format.trim());
                        if (length < value.length()) {
                            value = value.substring(0, length) + "...";
                        }
                    }
                } catch (Exception e) {
                    log.error("���Դ��󣺰�Ҫ�����ʾ��ʽ[format=" + format + "]�ض��ַ���?");
                    log.error(e);
                }
                break;
            case 2: // 2������
                value = this.getString(key);
                try {
                    @SuppressWarnings("unused")
                    BigInteger num = new BigInteger(value);
                } catch (Exception e1) {
                    if (value != null && !value.equals("")) {
                        if (value.equalsIgnoreCase("true")) {
                            value = "1";
                        }
                        if (value.equalsIgnoreCase("false")) {
                            value = "0";
                        }
                    }
                }
                break;
            case 3: // 3��������
                if (get(key) != null) {
                    value = get(key).toString();
                }
                try {
                    if (format != null && !format.equals("")) {
                        DecimalFormat df = new DecimalFormat();
                        df.applyLocalizedPattern(format);
                        double d = Double.parseDouble(value);
                        if (d != 0) {
                            value = df.format(Double.parseDouble(value));
                        } else {
                            value = "0";
                        }
                    }
                } catch (Exception e) {
                    log.error("��Ҫ��[format=" + format + "]��ʽ����������?");
                    log.error(e);
                    value = "[ERROR]";
                }
                break;
            case 4: // 4�����ı�
                value = "<textarea row='3' style='width:100%;'>" + this.getString(key, "") + "</textarea>";
                break;
            case 5: // 5��������
                value = "[��ý�����]";
                break;
            case 6: // 6��������
                try {
                    String patten = "";
                    Date date = this.getDate(key);
                    if (format != null && !format.equals("")) {
                        patten = format;
                    } else {
                        patten = "yyyy-MM-dd HH:mm:ss";
                    }
                    SimpleDateFormat df = new SimpleDateFormat(patten, Locale.CHINA);
                    value = df.format(date);
                } catch (Exception e) {
                    log.error("��Ҫ��[format=" + format + "]��ʽ������������ݳ��?");
                    log.error(e);
                    value = "[ERROR]";
                }
                break;

            default:
                value = this.getString(key);
                break;
        }

        return value == null ? "" : value.trim();
    }

    /**
     * ��ȡʵ��ֵ������������ء���������ݴ�����
     * ��ʱ���ԶԶ�����������ݵĴ���
     *
     * @param key
     * @param simple_type �����ͣ�1���ַ�  2������  3��������  4�����ı�  5��������  6��������
     * @param format      ��ʾ��ʽ
     * @return
     */
    public String getRealValue(String key, int simple_type, String format) {
        String value = "";
        if (this.get(key) == null) {
            return "";
        }

        switch (simple_type) {
            case 1: // 1���ַ�
                value = this.getString(key);
                break;
            case 2: // 2������
                value = this.getString(key);
                try {
                    @SuppressWarnings("unused")
                    BigInteger num = new BigInteger(value);
                } catch (Exception e1) {
                    if (value != null && !value.equals("")) {
                        if (value.equalsIgnoreCase("true")) {
                            value = "1";
                        }
                        if (value.equalsIgnoreCase("false")) {
                            value = "0";
                        }
                    }
                }
                break;
            case 3: // 3��������
                if (get(key) != null) {
                    value = get(key).toString();
                }
                try {
                    if (format != null && !format.equals("")) {
                        DecimalFormat df = new DecimalFormat();
                        df.applyLocalizedPattern(format);
                        double d = Double.parseDouble(value);
                        if (d != 0) {
                            value = df.format(Double.parseDouble(value));
                        } else {
                            value = "0";
                        }
                    }
                } catch (Exception e) {
                    log.error("��Ҫ��[format=" + format + "]��ʽ����������?");
                    log.error(e);
                    value = "[ERROR]";
                }
                break;
            case 4: // 4�����ı�
                value = this.getString(key);
                break;
            case 5: // 5��������
                value = "[��ý�����]";
                break;
            case 6: // 6��������
                try {
                    String patten = "";
                    Date date = this.getDate(key);
                    if (format != null && !format.equals("")) {
                        patten = format;
                    } else {
                        patten = "yyyy-MM-dd HH:mm:ss";
                    }
                    SimpleDateFormat df = new SimpleDateFormat(patten, Locale.CHINA);
                    value = df.format(date);
                } catch (Exception e) {
                    log.error("��Ҫ��[format=" + format + "]��ʽ������������ݳ��?");
                    log.error(e);
                    value = "[ERROR]";
                }
                break;

            default:
                value = this.getString(key);
                break;
        }

        return value == null ? "" : value.trim();
    }

    @Override
    public String toString() {
        StringBuffer sb = new StringBuffer();
        Set key_set = this.keySet();
        Iterator iter = key_set.iterator();
        while (iter.hasNext()) {
            String key = (String) iter.next();
            Object value = this.get(key);
            if (sb.toString().equals("")) {
                sb.append(key);
            } else {
                sb.append(",").append(key);
            }
            sb.append("=");
            sb.append(value);
        }

        return sb.toString();
    }

    public static void main(String[] args) {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd a", Locale.CHINA);
        String date_value = sdf.format(new Date());
        System.out.println(date_value);

        DecimalFormat df = new DecimalFormat();
        df.applyLocalizedPattern("#,##0.00");
        String float_value = df.format(1234567890123.14156d);
        System.out.println(float_value);

        df.applyLocalizedPattern("#.00%");
        String persent_value = df.format(3.14156d);
        System.out.println(persent_value);

        df.applyLocalizedPattern("00.###E0");
        String e_value = df.format(1234567890123.14156d);
		System.out.println(e_value);
	}
}

/*
@SuppressWarnings({"unchecked"})
public class Model<K, V> extends HashMap<K, V> {

    public Model set(K key, V value) {
        super.put(key, value);
        return this;
    }

    public <T> T take(V key) {
        return (T) super.get(key);
    }
}
*/
